<?php
require_once('Snoopy.class.php');

class DroopigBot {
  var $wiki_path;
  var $user;
  var $passwd;
  var $api_path;
  var $cache_path;
  var $verbose;
  var $snoopy;
  var $read_only;
  var $current_modification;
  function DroopigBot($user, $passwd, $url = "http://localhost/wiki", $verbose = false) {
    $this->user = $user;
    $this->passwd = $passwd;
    $this->wiki_path = $url;
    $this->api_path = $this->wiki_path."/api.php";
    $this->cache_path = "./cache";
    $this->verbose = $verbose;
    $this->snoopy = false;
    $this->read_only = true;
    $this->current_modification = false;
  }
  function unserialize($serial) {
    // Bug on my solaris version of PHP
    if($serial[0] == "\n") {
      $serial = substr($serial, 1);
    }
    return unserialize($serial);
  }
  function setCachePath($path) {
    $this->cache_path = $path;
  }
  function activateWrite() {
    $this->read_only = false;
  }
  function setVerbose($verbose = true) {
    $this->verbose = $verbose;
  }
  function setCurrentModification($mod) {
    $this->current_modification = $mod;
  }
  function connect() {
    if($this->snoopy) return;
    $this->snoopy = new Snoopy();
    $request_vars = array('action' => 'login', 'lgname' => $this->user, 'lgpassword' => $this->passwd, 'format' => 'php');
    if($this->verbose) {
      print "Connecting to: ".$this->api_path."\n";
      print_r($request_vars);
    }
    if(!$this->snoopy->submit($this->api_path, $request_vars))
      die("Snoopy error: {$this->snoopy->error}");

    $this->snoopy->setcookies();

    $connection_result = $this->unserialize($this->snoopy->results);

    if($this->verbose) print_r($connection_result);

    // Needed since MediaWiki 1.15.3
    if($connection_result["login"]["result"] == "NeedToken") {
      $request_vars["lgtoken"] = $connection_result["login"]["token"];
      if($this->verbose) print_r($request_vars);
      if(!$this->snoopy->submit($this->api_path, $request_vars))
        die("Snoopy error: {$this->snoopy->error}");
      if($this->verbose) print_r($this->unserialize($this->snoopy->results));
    }

    $request_vars = array('action' => 'query', 'meta' => 'userinfo', 'format' => 'php');
    if(!$this->snoopy->submit($this->api_path, $request_vars))
      die("Snoopy error: {$this->snoopy->error}");

    $array = $this->unserialize($this->snoopy->results);

    if($this->verbose) print_r($array);
    $userinfo = $array['query']['userinfo'];
    if(!array_key_exists('name', $userinfo)) {
      echo "Error while trying to login\n";
      exit(1);
    }
  }
  function getCacheName($title, $section = false) {
    $cache_file = $this->cache_path."/$title";
    if($section) $cache_file .= "-section-$section";
    return "$cache_file.wiki";
  }
  function getCache($title, $section = false) {
    return file_get_contents($this->getCacheName($title, $section));
  }
  function updateCache($title, $section = false) {
    if(!$this->snoopy) $this->connect();
    $request_vars = array('action' => 'query', 'format' => 'php',
                          'titles' => $title, 'prop' => 'revisions',
                          'rvprop' => 'timestamp|user|comment|content');

    if($section)
      $request_vars['rvsection'] = $section;
    if($this->verbose) print_r($request_vars);
    if(!$this->snoopy->submit($this->api_path, $request_vars))
      die("Snoopy error: {$this->snoopy->error}");

    $array = $this->unserialize($this->snoopy->results);
    if($this->verbose) print_r($array);

    $file = fopen($this->getCacheName($title, $section), 'w');
    $current_page = current($array['query']['pages']);
    fwrite($file, $current_page['revisions'][0]['*']);
    fclose($file);
    if($this->verbose) print_r($array);
    return $array;
  }
  function getSectionId($content, $section_title, $re = false) {
    if(!$this->snoopy) $this->connect();
    $request_vars = array('action' => 'parse', 'format' => 'php',
                          'text' => $content);
    if(!$this->snoopy->submit($this->api_path, $request_vars))
      die("Snoopy error: {$this->snoopy->error}");
    $array = $this->unserialize($this->snoopy->results);
    if($this->verbose) print_r($array);
    $sections = array();
    foreach($array['parse']['sections'] as $section) {
      if($section_title == $section['line'] || ($re && preg_match("/$section_title/", $section['line']))) {
        $sections[$section['number']] = $section['line'];
      }
    }
    if(count($sections) == 0) return false;
    return $sections;
  }
  function exist($title, $section = false, $edit = false) {
    $request_vars = array('action' => 'query', 'meta' => 'userinfo', 'format' => 'php',
                          'titles' => $title, 'prop' => 'info|revisions');
    if($edit)
      $request_vars['intoken'] = 'edit';

    if(!$this->snoopy->submit($this->api_path, $request_vars))
      die("Snoopy error: {$this->snoopy->error}");

    $array = $this->unserialize($this->snoopy->results);
    if($this->verbose) print_r($array);
    return $array;
  }
  function updateArticle($title, $section = false, $content = false, $create_only = false) {
    if($this->read_only) return;
    if(!$this->snoopy) $this->connect();
    $array = $this->exist($title, $section, true);

    $tmp = current($array['query']['pages']);
    $edit_token = urlencode($tmp['edittoken']);
    if($this->verbose) print "Edit token : $edit_token\n";
    if(!isset($tmp['edittoken'])) {
      print "Error while trying to edit '$title'\n";
      return false;
    }
    if($create_only) {
      print "Article '$title' already exist\n";
      return false;
    }
    $create = "&createonly";
    if(is_array(current($array['query']['pages']))) {
      $create = "";
    }
    if(!$content)
    $content = $this->getCache($title, $section);
    $request_vars = array('action' => 'edit', 'notminor' => true, 'bot' => true,
			  'title' => $title,
			  'text' => $content,
			  'token' => $tmp['edittoken'],
			  'meta' => 'userinfo', 'format' => 'php');
    if($this->verbose)
      print_r($request_vars);
    if($this->current_modification) {
      $request_vars['summary'] = $this->current_modification;
    }
    if($section) {
      $request_vars['section'] = $section;
    }
    if($this->verbose) {
      print "Submiting query : ".$this->api_path."?action=edit$create\n";
    }
    if(!$this->snoopy->submit($this->api_path."?action=edit$create", $request_vars))
      die("Snoopy error: {$this->snoopy->error}");
    $array = $this->unserialize($this->snoopy->results);
    if($this->verbose) {
      print $this->snoopy->results."\n";
      print_r($array);
    }
    return $array;
  }
  function close() {
    $this->snoopy = false;
  }
}

?>
